#ifndef _Mutation_Gaussian_H_
#define _Mutation_Gaussian_H_

#include "../../Elements/Chromosome.h"
#include "Mutation.h"

#include "../../Rng/GlobalRng.h"

using namespace std;

/********************************************************************
Headers
********************************************************************/
/*!
 * \brief
 * Implementation of Gaussian mutation (applicable for real-coded chromosomes).
 *  
 * \see
 * Mutation | Mutation_BitFlip
 */
class Mutation_Gaussian : public Mutation<double> {

public:
	Mutation_Gaussian(double pMutation);

	virtual bool mutate(Chromosome<double>& chromosome);
	
	/*!
	 * \brief
	 * The sigma value for the Gaussian distribution.
	 */
	double sigma;
private:
	
};

/********************************************************************
Implementation
********************************************************************/
Mutation_Gaussian::Mutation_Gaussian(double pMutation) : Mutation<double>(pMutation)
{
	sigma = 1.0;
}


bool Mutation_Gaussian::mutate(Chromosome<double>& chromosome)
{
	//double randomNumber = Rng::uni();
	//if (randomNumber > this->pMutation) return false;

	for (unsigned int i=0; i<chromosome.size(); i++)
	{
		double randomNumber = Rng::uni();

		if (randomNumber <= pMutation) 
		{
			double tmpSigma = sigma;
			double tmp;
			do {
				tmp = Rng::gauss(0, tmpSigma);
				tmpSigma /= 10;
			} while (chromosome[i] + tmp < chromosome.lowerBounds[i] || chromosome[i] + tmp > chromosome.upperBounds[i]);

			chromosome[i] += tmp;
		}
	}

	return true;
}

#endif
